package com.espirit.eap.manager.workflow;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.Transient;

import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;

import com.espirit.EntityMapping;
import com.espirit.eap.ICheckModelDuplicateInfo;
import com.espirit.eap.annotation.DomainModel;
import com.espirit.eap.annotation.ModelDisplayProperty;
import com.espirit.eap.sa.LoginUser;
import com.googlecode.cswish.model.Saas;

@Entity
@DomainModel
@ModelDisplayProperty("name")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class WFPhase extends EntityMapping implements ICheckModelDuplicateInfo, Saas {

	private static final long serialVersionUID = 7184349304310042309L;
	private String name;
	private String description;
	private List<LoginUser> users;
	private Integer needAcceptUsers;
	private WFCondition wfCondition;
	
	private Integer sid;
	public Integer getSid() {
		return sid;
	}

	public void setSid(Integer sid) {
		this.sid = sid;
	}

	@Column(length=50)
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	public void setDescription(String description) {
		this.description = description;
	}
	public String getDescription() {
		return description;
	}
	
	@ManyToMany(targetEntity=LoginUser.class, fetch=FetchType.LAZY)
	@JoinTable(name = "saas_wfphaseusers", joinColumns = @JoinColumn(name = "wfphase_id"), inverseJoinColumns = @JoinColumn(name = "user_id")  ) 
	public List<LoginUser> getUsers() {
		return users;
	}
	
	public void setUsers(List<LoginUser> users) {
		this.users = users;
	}
	
	public List<LoginUser> safeUsers(){
		if (users == null){
			users = new ArrayList<LoginUser>();
		}
		return users;
	}
	
	public void initUsers(){
		if (this.getUsers() != null ) {
			List<LoginUser> users = this.getUsers();
			for(int i = 0; i < users.size() ; i++){
				LoginUser user = users.get(i);
				user = user.getUsers();
				users.set(i, user);
			}
		}
	}
	
	private WFPhase wfPhase;
	@Transient
	public WFPhase getWfPhases(){
		return wfPhase;
	}
	public void setWfPhases(WFPhase phase){
		this.wfPhase = phase;
	}
	
	@Transient
	public boolean isTheLastUser(LoginUser user){
		if (this.getUsers() != null){
			List<LoginUser> users = this.getUsers();
			if (users.get(users.size() -1).getId().equals(user.getId())){
				return true;
			}
		}
		return false;
	}
	@Transient
	public LoginUser getNextUser(LoginUser user) {
		if (this.getUsers() != null){
			List<LoginUser> users = this.getUsers();
			int size = users.size();
			if (size > 0 && user == null){
				return users.get(0);
			}
			for(int i = 0 ; i < size ; i++){
				if (users.get(i).getId().equals(user.getId())){
					if (i == size -1){
						return null;
					} else {
						return users.get(++i);
					}
				}
			}
		}
		return null;
	}
	private final static String[] gatherProperties = new String[]{"name"};
	@Override
	public String[] gatherProperties() {
		return gatherProperties;
	}
	public Integer getNeedAcceptUsers() {
		return needAcceptUsers;
	}
	public void setNeedAcceptUsers(Integer needAcceptUsers) {
		this.needAcceptUsers = needAcceptUsers;
	}
	
	public Integer safeNeedAcceptUsers(){
		return needAcceptUsers == null ? 0 : needAcceptUsers; 
	}
	
	@ManyToOne(targetEntity=WFCondition.class,fetch=FetchType.LAZY ,cascade = CascadeType.ALL)
	public WFCondition getWfCondition() {
		return wfCondition;
	}
	public void setWfCondition(WFCondition wfCondition) {
		this.wfCondition = wfCondition;
	}
	public WFCondition safeWFCondtion(){
		if (this.wfCondition == null){
			this.wfCondition = new WFCondition();
		}
		return this.wfCondition;
	}
	
	
	public void verify(){
		if (wfCondition != null ){
			wfCondition.verify();
		}
	}
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		WFPhase other = (WFPhase) obj;
		if (getId() == null) {
			if (other.getId() != null)
				return false;
		} else if (!getId().equals(other.getId()))
			return false;
		return true;
	}
	
	
	
}
